
package com.eva.android;

import android.util.Log;

import com.x52im.rbchat.IMClientManager;
import com.x52im.rbchat.MyApplication;

import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

/**
 * 一个用于HttpsURLConnection的https配置的工具类。
 *
 * @author Jack Jiang
 * @since 8.4
 */
public class HttpsUtils {
    private final static String TAG = HttpsUtils.class.getSimpleName();

    /**
     * 根据url的前缀，自动判断是否是https，并返回相应的HttpURLConnection对象。
     *
     * @param httpUrl http请求的原始url
     * @return 返回HttpURLConnection对象
     * @throws Exception
     */
    public static HttpURLConnection getHttpURLConnectionAuto(String httpUrl) throws Exception {
        boolean isHttps = isHttps(httpUrl);
        HttpURLConnection c;

        if(isHttps) {
            SSLSocketFactory ssf = createSSLSocketFactory();
            HttpsURLConnection conn = (HttpsURLConnection)new URL(httpUrl).openConnection();
//			conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:26.0) Gecko/20100101 Firefox/26.0");
//			conn.setRequestMethod("POST");
//			conn.setRequestProperty("Content-Type", "plain/text; charset=UTF-8");
            conn.setHostnameVerifier(new NullHostNameVerifier());//!
            conn.setSSLSocketFactory(ssf);//!

            // v10.0版开始，为了规范文件上传token传递规范，目前取消了通过formData传自定义token字段，改为使用RFC标准的Authorization http头形式传输
            conn.setRequestProperty("Authorization", IMClientManager.getTokenSafe());

            Log.i(TAG, "【HTTPS】HttpsURLConnection 初始设置完成 (url= " + httpUrl+")");

            c = conn;
        } else {
            c = (HttpURLConnection)new URL(httpUrl).openConnection();
        }

        return c;
    }

    /**
     * 创建SSLSocketFactory对象。
     *
     * @return 返回新对象
     * @throws Exception
     */
    public static SSLSocketFactory createSSLSocketFactory() throws Exception {
        X509TrustManager x509mgr = new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] xcs, String string) {
            }

            @Override
            public void checkServerTrusted(X509Certificate[] xcs, String string) {
            }

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };

        TrustManager[] tm = {x509mgr};
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, tm, new java.security.SecureRandom());
        // 从上述SSLContext对象中得到SSLSocketFactory对象
        SSLSocketFactory ssf  = sslContext.getSocketFactory();
        return ssf;
    }

    /**
     * URL是否是https协议。
     *
     * @return true
     * @since 8.4
     */
    public static boolean isHttps(String httpUrl) {
        return httpUrl != null && httpUrl.toLowerCase().startsWith("https:");
    }

    /**
     * HostnameVerifier实现类，开发者可以在此类中进行https域名检验。
     *
     * @since 8.4
     */
    public static class NullHostNameVerifier implements HostnameVerifier {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            Log.i(TAG, "【HTTPS】Approving certificate for " + hostname);
            // FIXME: 为了减化https的使用，此处不进行域名校验，建议在强安全环境下，自行启用检验！
            return true;
        }
    }
}
